#if 1
#include "face_sqlite3.hpp"

sqlite3 *db = NULL;
sqlite3_stmt *stmt = NULL;

int open_databases() // is_exist当前数据库存在与否标志 存在：1，不存在：0
{
    int rc = -1;
    char *err_msg = NULL;
    char *sql = NULL;
    bool is_exist = false;

    if (access("face_data.db", F_OK) == 0)
    {
        cout << "face_data.db is exist ..." << endl;
        is_exist = true;
    }
    else
    {
        is_exist = false;
    }

    rc = sqlite3_open_v2("face_data.db", &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_open error ...%s\n", sqlite3_errmsg(db));
        sqlite3_close_v2(db);
        return -1;
    }
    else
    {
        cout << "Open sqlite3 databases successfully ..." << endl;
    }
    if (is_exist == false)
    {
        sql = "create table face_table("
              "name text,"
              "featureSize integer,"
              "feature blob);";

        rc = sqlite3_exec(db, sql, NULL, 0, &err_msg);
        if (rc != SQLITE_OK)
        {
            fprintf(stderr, "SQL error: %s\n", err_msg);
            sqlite3_free(err_msg);
            sqlite3_close_v2(db);
            return -1;
        }
        sqlite3_free(err_msg);
    }
    return 0;
}

int insert_face_data_to_databases(const char *name, int featureSize, float feature[512])
{
#if 1
    if (open_databases() != 0)
    {
        cout << "open_databases error ..." << __func__ << endl;
        return -1;
    }
#endif

    int rc = -1;
    char *sql = "insert into face_table(name, featureSize, feature) values(?, ?, ?);"; // 第一个分号是告诉解析器命令解析到此位置结束，这里使用参数化查询，对用户输入的数据进行处理，防止注入风险
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);                                 // 参数预处理
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_prepare_v2 error ...%s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return -1;
    }
    // 注意Sqlite3中参数绑定的索引是从1开始的！！！
    sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC); //-1表示让数据库自动计算字符串长度遇\0终止, static表示这个数据内存由用户手动管理，无需SQLTTE介入
    sqlite3_bind_int(stmt, 2, featureSize);
    sqlite3_bind_blob(stmt, 3, feature, featureSize, SQLITE_STATIC); // 这里blob数据是二进制类型且数据大小不能给-1，必须给具体大小，大小以字节为单位！！！

    rc = sqlite3_step(stmt); // 执行数据插入
#if 1
    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "sqlite3_step error ...%s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        sqlite3_close(db);
        return -1;
    }
    cout << "insert face data successfully..." << endl;
    sqlite3_finalize(stmt); // 先销毁预处理语句
    sqlite3_close(db);      // 关闭数据库
#endif

    return 0;
}

map<string, rockx_face_feature_t> get_face_feature_to_map()
{
    char *name = NULL;
    rockx_face_feature_t face_feat;
    memset(&face_feat, 0, sizeof(rockx_face_feature_t));
    map<string, rockx_face_feature_t> rockx_face_feature_map;

#if 1
    if (open_databases() != 0)
    {
        cout << "open_databases error ..." << __func__ << endl;
        return rockx_face_feature_map;
    }
#endif

    int rc = -1;
    char *sql = "select * from face_table;";
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        cout << "sqlite3_prepare_v2 error ..." << __func__ << endl;
        sqlite3_close(db);
        return rockx_face_feature_map;
    }

    cout << endl
         << "###############################################" << endl;
    cout << "--------------Sqlite databases area------------" << endl;
    while (sqlite3_step(stmt) == SQLITE_ROW) // 表示当前行是否还有数据要处理
    {
        name = (char *)sqlite3_column_text(stmt, 0); // 这里查询列的索引是从0开始的与参数绑定的索引是不同的！！！
        cout << "name:" << name << endl;
        face_feat.len = sqlite3_column_int(stmt, 1);
        cout << "featureSize:" << face_feat.len << endl;
        memset(face_feat.feature, 0, sizeof(face_feat.feature)); // 这一步必须清，保证下次插入数据的准确
        memcpy(face_feat.feature, sqlite3_column_blob(stmt, 2), face_feat.len);
        rockx_face_feature_map.insert(pair<string, rockx_face_feature_t>(string(name), face_feat)); // map容器键值对插入规范
    }
    cout << "###############################################" << endl
         << endl;
    sqlite3_finalize(stmt);
    sqlite3_close_v2(db);
    return rockx_face_feature_map;
}
#endif